package com.wuyan.web.auth.api;

import com.wuyan.helper.kit.endecryption.EncryptionHelper;
import com.wuyan.web.auth.entity.PubAccount;
import com.wuyan.web.auth.form.LoginSubjectForm;
import com.wuyan.web.auth.repo.PubAccountExtendRepo;
import com.wuyan.web.auth.service.LoginService;
import com.wuyan.web.base.aop.ApiLogAnnotation;
import com.wuyan.web.base.helper.BaseApi;
import com.wuyan.web.base.helper.DataEncryptionHelper;
import com.wuyan.web.base.helper.auth.LoginInfo;
import com.wuyan.web.base.helper.rep.RepBody;
import com.wuyan.web.base.helper.rep.RepCodeEnum;
import com.wuyan.web.base.helper.rep.RepHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;

import static com.wuyan.web.base.config.EntityConfig.DATA_ENCRYPTION;

@Slf4j
@RestController
@RequestMapping("/api/login")
public class LoginApi extends BaseApi implements RepHelper {
    @Autowired
    private PubAccountExtendRepo pubAccountExtendRepo;

    @Autowired
    private LoginService loginService;

    @Value("${wuyan.login.verify-code}")
    private boolean verifyCode;

    /**
     * 账户密码登录
     *
     * @param request 请求体
     * @param form    参数
     * @return RepBody<LoginInfo>
     */
    @PostMapping
    @ApiLogAnnotation(name = "login:loginByAccount")
    public RepBody<LoginInfo> loginByAccount(HttpServletRequest request, HttpServletResponse response,
                                             @RequestBody @Validated LoginSubjectForm form)
            throws Exception {
        /*
            验证码校验
         */
        if (verifyCode) {
            Enumeration<String> headerNames = request.getHeaderNames();
            String codeSecret = request.getHeader(VerifyCodeApi.HEADER_AUTH_KEY_NAME);
            if (StringUtils.isBlank(codeSecret)) {
                codeSecret = request.getHeader(VerifyCodeApi.HEADER_AUTH_KEY_NAME2);
            }
            if (StringUtils.isBlank(codeSecret)) {
                return error(RepCodeEnum.ERR_LOGIN_VERIFY_AUTH);
            }

            String code = getAttr(request, codeSecret, String.class, true);
            if (StringUtils.isBlank(code)) {
                return error(RepCodeEnum.ERR_LOGIN_VERIFY_INVALID);
            }

            if (!code.equals(form.getCode().toUpperCase())) {
                return error(RepCodeEnum.ERR_LOGIN_VERIFY);
            }
        }

        /*
            账户校验
         */
        PubAccount pubAccount = pubAccountExtendRepo
                .findFirstByUsernameOrPhone(form.getKey(), form.getKey());
        if (null == pubAccount) {
            return error(RepCodeEnum.ERR_LOGIN_USERNAME);
        }

        if (pubAccount.getStatus() != 1) {
            return error(RepCodeEnum.ERR_LOGIN_STATUS);
        }

        if (!pubAccount.getPassword().equals(EncryptionHelper.getInstance().md5(form.getPwd()))) {
            return error(RepCodeEnum.ERR_LOGIN_PASSWORD);
        }

        LoginInfo loginInfo = loginService.saveLoginInfo(request, response, pubAccount);
        return ok(loginInfo);
    }

    /**
     * 重置密码
     *
     * @param request 请求体
     * @param form    数据
     * @return RepBody<PubViewAccount>
     */
    @PostMapping("/reset-pwd")
    @ApiLogAnnotation(name = "login:resetPwd")
    public RepBody<Boolean> resetPwd(HttpServletRequest request,
                                     @RequestBody Map<String, Object> form) throws Exception {
        String ak = form.containsKey("ak") ? form.get("ak").toString() : "";
        String code = getAttr(request, "resetPwd-" + ak, String.class, true);

        if (null == code) {
            return error(RepCodeEnum.ERR_LOGIN_VERIFY_INVALID);
        }
        if (!code.equals(form.get("code").toString().toUpperCase())) {
            return error(RepCodeEnum.ERR_LOGIN_VERIFY);
        }

        String username = form.containsKey("key") ? form.get("key").toString() : "";
        String password = form.containsKey("pwd") ? form.get("pwd").toString() : "";

        PubAccount pubAccount = pubAccountExtendRepo.findFirstByUsername(username);
        if (null == pubAccount) {
            return error(RepCodeEnum.ERR_LOGIN_USERNAME);
        }

        // 需要加密
        pubAccount.setPassword(password);
        DataEncryptionHelper.encode("pubAccount", pubAccount, DATA_ENCRYPTION);
        pubAccountExtendRepo.save(pubAccount);

        return ok(true);
    }
}
